package amdocs.jet.pm.safenote;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.restlet.engine.Engine;
import org.restlet.ext.net.HttpClientHelper;
import org.restlet.resource.ClientResource;

import amdocs.jet.pm.Constants;
import amdocs.jet.pm.PersonalManagerActivity;
import amdocs.jet.pm.Utils;
import amdocs.jet.pm.safenote.common.SafeNote;
import amdocs.jet.pm.safenote.common.SafeNoteList;
import amdocs.jet.pm.safenote.common.SafeNoteResource;
import android.app.AlertDialog;
import android.app.ExpandableListActivity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.ExpandableListContextMenuInfo;
import android.widget.ImageView;
import android.widget.SimpleExpandableListAdapter;
import android.widget.TextView;
import android.widget.Toast;

import com.amdocs.jet.pm.R;

public class SafeNoteActivity extends ExpandableListActivity 
{
	public SafeNoteExpandableListAdapter safeNoteListAdapter;
	public Button clearFilterButton;
	public EditText clearFilterEditText;
	public SafeNoteList safeNoteList;
	public SafeNoteResource safeNoteResource;
	public ClientResource clientResource;
	public ArrayList<String> categoryList = new ArrayList<String>();
    public List<Map<String, String>> categoryData = new ArrayList<Map<String, String>>();
    public List<List<Map<String, String>>> childSafeNoteData = new ArrayList<List<Map<String, String>>>();
    public InputMethodManager inputMethodManager;
    public String safeNoteId2BeDeleted;
    
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) 
    {
    	super.onCreate(savedInstanceState);
    	setContentView(R.layout.safanote_screen);
    	initControls();
    	setListeners();
		Engine.getInstance().getRegisteredClients().clear();
		// Add the "net" client connector
//		Engine.getInstance().getRegisteredClients().add(new HttpClientHelper(new Client(Protocol.HTTP)));
//		Engine.getInstance().getRegisteredClients().add(new HttpClientHelper(new Client(Protocol.HTTPS)));
		Engine.getInstance().getRegisteredClients().add(new HttpClientHelper(null)); 
    	retrieveNoteList();
    	inputMethodManager.hideSoftInputFromWindow(clearFilterEditText.getWindowToken(), 0);
    }
    
    private void initControls()
    {
    	inputMethodManager = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
        clearFilterButton = (Button) findViewById(R.id.clearFilterNotesButton);
        clearFilterEditText = (EditText) findViewById(R.id.filterNotesEditText);
        clearFilterEditText.setInputType(0);
    }
    
    private void setListeners() 
    {
		//listener to clear filter search notes
    	clearFilterButton.setOnClickListener(new View.OnClickListener() {
			public void onClick(View view) 
			{
				clearFilterEditText.setText("");
				safeNoteListAdapter.notifyDataSetChanged();
				initCategoryList();
				safeNoteListAdapter.notifyDataSetChanged();
				inputMethodManager.hideSoftInputFromWindow(clearFilterEditText.getWindowToken(), 0);
			}
		});
    	
		//listener to clear filter search notes
    	clearFilterEditText.setOnKeyListener(new View.OnKeyListener() {
			public boolean onKey(View v, int keyCode, KeyEvent event) 
			{
				safeNoteListAdapter.notifyDataSetChanged();
				initCategoryList();
				safeNoteListAdapter.notifyDataSetChanged();
				return false;
			}
		}); 
    }
    
	private void updateListAdapter() 
	{
		this.safeNoteListAdapter = new SafeNoteExpandableListAdapter(
                this,
                categoryData,
                R.layout.safenote_category_item_row,
                new String[] { Constants.SAFE_NOTE_CATEGORY },
                new int[] { R.id.safeNoteCategoryNameRow },
                childSafeNoteData,
                R.layout.safenote_item_list_row,
                new String[] { Constants.SAFE_NOTE_ID, Constants.SAFE_NOTE_NAME },
                new int[] { R.id.safeNoteNameRow, R.id.safeNoteNameRow }
                );
        setListAdapter(safeNoteListAdapter);
        ExpandableListView expandableListView = getExpandableListView();
        expandCollapseList(expandableListView);
        registerForContextMenu(expandableListView);
	}

	public void expandCollapseList(ExpandableListView expandableListView)
	{
		int groupCount = expandableListView.getCount();
        for (int i = 0; i < groupCount; i++)
        {
            if (clearFilterEditText.getText().toString().length() > 0)
            {
            	expandableListView.expandGroup(i);
            }
            else
            {
            	expandableListView.collapseGroup(i);
            }
        }
	}
	
	public boolean onCreateOptionsMenu(Menu menu) 
	{
		MenuInflater inflater = getMenuInflater();
	    inflater.inflate(R.menu.safenote_menu, menu);
		return true;
	}

	public boolean onMenuItemSelected(int featureId, MenuItem item) 
	{
		switch (item.getItemId()) 
		{
			case R.id.safenoteRefreshMenuItem:
				retrieveNoteList();
				break;
			case R.id.safenoteAddMenuItem:
				Bundle bundle = new Bundle();
				SafeNote safeNote = new SafeNote();
				bundle.putSerializable(Constants.KEY_SAFE_NOTE, safeNote);
				bundle.putSerializable(Constants.KEY_ACTION, SafeNoteActionEnum.ADD);
				bundle.putStringArrayList(Constants.KEY_CATEGORIES, categoryList);
				Intent addSafeNoteIntent = new Intent(this.getApplicationContext(), AddSafeNoteActivity.class);
				addSafeNoteIntent.putExtras(bundle);
				startActivityForResult(addSafeNoteIntent, SafeNoteActionEnum.ADD.ordinal());
				break;
			case R.id.safenoteSettingsMenuItem:
				Toast.makeText(this, "This option is not available", 7000).show();
				break;
			case R.id.exitMenuItem:
				finish();
				break;			
			default:
				super.onMenuItemSelected(featureId, item);
				break;
		}
		return true;
	}
	
	@Override
	public void onCreateContextMenu(ContextMenu menu, View v,
	                                ContextMenuInfo menuInfo) 
	{
		ImageView safeNoteIconImageView = (ImageView)v.findViewById(R.id.safeNoteIconRow);
		if (safeNoteIconImageView != null)
		{
			menu.setHeaderIcon(safeNoteIconImageView.getDrawable());
		}
		TextView safeNoteName = (TextView)v.findViewById(R.id.safeNoteNameRow);
		if (safeNoteName != null)
		{
			menu.setHeaderTitle(safeNoteName.getText().toString());
		}
		super.onCreateContextMenu(menu, v, menuInfo);
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.safenote_context_menu, menu);
	}
	
	@Override
	public boolean onContextItemSelected(MenuItem item) {
	  ExpandableListContextMenuInfo info = (ExpandableListContextMenuInfo) item.getMenuInfo();
	  switch (item.getItemId()) 
	  {
		  case R.id.editSafenoteMenuItem:
		    editNote(info.targetView);
		    return true;
		  case R.id.deleteSafenoteMenuItem:
			  deleteConfirmationDialog(info.targetView);
		    return true;
		  default:
	    return super.onContextItemSelected(item);
	  }
	}
	
	protected void onActivityResult(int requestCode, int resultCode, Intent returnIntent)
	{
		String message;
        SafeNote safeNote;
        SafeNoteActionEnum safeNoteAction;
        if (returnIntent == null)
        {
        	return;
        }
        Bundle bundle = returnIntent.getExtras();
        if (bundle == null)
        {
        	return;
        }
        safeNote = (SafeNote)bundle.getSerializable(Constants.KEY_SAFE_NOTE);
    	safeNoteAction = (SafeNoteActionEnum)bundle.getSerializable(Constants.KEY_ACTION);
    	message = bundle.getString(Constants.KEY_MESSAGE);
		if (resultCode == RESULT_OK)
		{
        	if (SafeNoteActionEnum.EDIT.equals(safeNoteAction))
        	{
        		safeNoteList.updateSafeNote(safeNote);
        		initCategoryList();
        	}
        	else if (SafeNoteActionEnum.DELETE.equals(safeNoteAction))
        	{
        		safeNoteList.removeSafeNote(safeNote);
        		initCategoryList();
        	}
        	else if (SafeNoteActionEnum.ADD.equals(safeNoteAction))
        	{
        		retrieveNoteList();
        	}
		}
		if (message != null && message.trim().length() != 0)
		{
			Toast.makeText(this, message, 7000).show();
		}
	}
	
	public void deleteConfirmationDialog(View view)
	{
		TextView safeNoteIDTextView = (TextView)view.findViewById(R.id.safeNoteIDRow);
		if (safeNoteIDTextView != null)
		{
			safeNoteId2BeDeleted = safeNoteIDTextView.getText().toString();
		}

		AlertDialog.Builder builder = new AlertDialog.Builder(this);
		builder.setMessage(R.string.string_are_you_sure_you_want_to_delete)
		       .setCancelable(false)
		       .setPositiveButton(R.string.string_yes, new DialogInterface.OnClickListener() {
		           public void onClick(DialogInterface dialog, int id) {
					deleteSafeNote();
		           }
		       })
		       .setNegativeButton(R.string.string_no, new DialogInterface.OnClickListener() {
		           public void onClick(DialogInterface dialog, int id) {
		                dialog.cancel();
		           }
		       });
		AlertDialog alert = builder.create();
		alert.show();
	}
	
    private void deleteSafeNote() {
    	clientResource = new ClientResource(Constants.APP_ENGINE_SERVER_URL + "/delete/" + safeNoteId2BeDeleted);
    	safeNoteResource = clientResource.wrap(SafeNoteResource.class);
    	safeNoteResource.remove(safeNoteId2BeDeleted);
//    	if ("".equals(clientResource.getStatus()))
//    	{
    		for (SafeNote safeNote : safeNoteList.getSafeNotelist()) 
    		{
				if (safeNote.getSafeNoteID().equals(safeNoteId2BeDeleted))
				{
					safeNoteList.removeSafeNote(safeNote);
					initCategoryList();
					Toast.makeText(this, "The safe note is deleted", 7000).show();
					break;
				}
			}
//    	}
	}

	private void editNote(View selectedSafeNoteView) 
	{
		SafeNote safeNote = Utils.convertSelectedNoteView2SafeNote(selectedSafeNoteView);
		Bundle bundle = new Bundle();
		bundle.putSerializable(Constants.KEY_ACTION, SafeNoteActionEnum.EDIT);
		bundle.putSerializable(Constants.KEY_SAFE_NOTE, safeNote);
		bundle.putStringArrayList(Constants.KEY_CATEGORIES, categoryList);
		Intent addSafeNoteIntent = new Intent(this.getApplicationContext(), AddSafeNoteActivity.class);
		addSafeNoteIntent.putExtras(bundle);
		startActivityForResult(addSafeNoteIntent, SafeNoteActionEnum.EDIT.ordinal());
	}
	
    public boolean onChildClick(ExpandableListView parent, View v, int groupPosition,
            int childPosition, long id) {
		SafeNote safeNote = Utils.convertSelectedNoteView2SafeNote(v);
		Bundle bundle = new Bundle();
		bundle.putSerializable(Constants.KEY_ACTION, SafeNoteActionEnum.VIEW);
		bundle.putSerializable(Constants.KEY_SAFE_NOTE, safeNote);
		bundle.putStringArrayList(Constants.KEY_CATEGORIES, categoryList);
		Intent addSafeNoteIntent = new Intent(this.getApplicationContext(), AddSafeNoteActivity.class);
		addSafeNoteIntent.putExtras(bundle);
		startActivityForResult(addSafeNoteIntent, SafeNoteActionEnum.VIEW.ordinal());
        return false;
    }

	private void retrieveNoteList()
    {
    	String user = "vogash@gmail.com";
    	clientResource = new ClientResource(Constants.APP_ENGINE_SERVER_URL + "/get/" + user);
		safeNoteResource = clientResource.wrap(SafeNoteResource.class);
		//clientResource.setRetryOnError(true);
		safeNoteList = safeNoteResource.retrieve(user);
    	if (safeNoteList != null)
    	{
    		initCategoryList();
    	}   		
    }
    
    private void initCategoryList()
    {
		String filterText = "";
		boolean isDoFilter = false;
		if (clearFilterEditText.getText() != null)
		{
			filterText = clearFilterEditText.getText().toString();
			isDoFilter = true;
		}
    	String categoryName;
        Map<String, String> curCategoryMap = null;
        Map<String, String> curSafeNoteChildMap = null;
        List<Map<String, String>> childrens;
        Map<String,List<Map<String, String>>> categoryChildrens = new HashMap<String,List<Map<String, String>>>();
        categoryData.clear();
        childSafeNoteData.clear();
        categoryList.clear();
        for (SafeNote safeNote : safeNoteList.getSafeNotelist()) 
        {
        	if (!categoryList.contains(safeNote.getSafeNoteCategoryName()))
        	{
        		categoryList.add(safeNote.getSafeNoteCategoryName());
        	}
        	
        	if (isDoFilter)
        	{
	        	if (safeNote.getSafeNoteName() != null && safeNote.getSafeNoteName().length() != 0 && !(safeNote.getSafeNoteName().toLowerCase().indexOf(filterText) >= 0))
	        	{
	        		continue;
	        	}
        	}
        	categoryName = safeNote.getSafeNoteCategoryName();
        	curCategoryMap = new HashMap<String, String>();
        	curSafeNoteChildMap = new HashMap<String, String>();
        	curCategoryMap.put(Constants.SAFE_NOTE_CATEGORY, categoryName);
            curSafeNoteChildMap.put(Constants.SAFE_NOTE_ID, safeNote.getSafeNoteID());
            curSafeNoteChildMap.put(Constants.SAFE_NOTE_NAME, safeNote.getSafeNoteName());
            curSafeNoteChildMap.put(Constants.SAFE_NOTE_ICON, safeNote.getSafeNoteIcon());
            curSafeNoteChildMap.put(Constants.SAFE_NOTE_CATEGORY, categoryName);
            curSafeNoteChildMap.put(Constants.SAFE_NOTE_BODY, safeNote.getSafeNoteBody());
            
			if (!categoryData.contains(curCategoryMap))
			{
				categoryData.add(curCategoryMap);
			}
			
			if (!categoryChildrens.containsKey(categoryName))
			{
				childrens = new ArrayList<Map<String, String>>();
				categoryChildrens.put(categoryName, childrens);
			}
			categoryChildrens.get(categoryName).add(curSafeNoteChildMap);
        }
        for (Map<String, String> category : categoryData) 
        {
        	categoryName = category.get(Constants.SAFE_NOTE_CATEGORY);
        	childSafeNoteData.add(categoryChildrens.get(categoryName));
        }

        updateListAdapter();
    }
    
    class SafeNoteExpandableListAdapter extends SimpleExpandableListAdapter 
    {
    	private Context mContext;
    	private String mFilterText;
    	public List<String> categoryList;
    	List<Map<String, String>> mGroupData;
        List<List<Map<String, String>>> mChildData;
        private Bitmap noteIcon;
        
        public SafeNoteExpandableListAdapter(Context context,
                List<Map<String, String>> groupData, int groupLayout,
                String[] groupFrom, int[] groupTo,
                List<List<Map<String, String>>> childData,
                int childLayout, String[] childFrom, int[] childTo) {
            super(context, groupData, groupLayout, groupLayout, groupFrom, groupTo, childData,
                    childLayout, childLayout, childFrom, childTo);
            mContext = context;
            mGroupData = groupData;
            mChildData = childData;
        }

        public int getChildrenCount(int groupPosition) 
        {
        	return mChildData.get(groupPosition).size();
        }
        
        public View getChildView(int groupPosition, int childPosition, boolean isLastChild,
                View convertView, ViewGroup parent) {
            View view = convertView;
            Map<String, String> child = mChildData.get(groupPosition).get(childPosition);
            String safeNoteIcon = child.get(Constants.SAFE_NOTE_ICON);
            String safeNoteName = child.get(Constants.SAFE_NOTE_NAME);
            String safeNoteID = child.get(Constants.SAFE_NOTE_ID);
            String safeNoteCategory = child.get(Constants.SAFE_NOTE_CATEGORY);
            String safeNoteBody = child.get(Constants.SAFE_NOTE_BODY);
            
            if (view == null) {
                LayoutInflater vi = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                view = vi.inflate(R.layout.safenote_item_list_row, null);
            }
            
			// Set safe note id text
			TextView safeNoteIDTextView = (TextView)view.findViewById(R.id.safeNoteIDRow);
			if (safeNoteIDTextView != null)
			{
				safeNoteIDTextView.setText(safeNoteID);
			}
			
			// Set safe note icon 
            ImageView imageView = (ImageView) view.findViewById(R.id.safeNoteIconRow);
            try {
            	noteIcon = BitmapFactory.decodeStream(mContext.getAssets().open("safenote/" + safeNoteIcon));
				imageView.setImageBitmap(noteIcon);
			} catch (IOException e) {e.printStackTrace();}
			
			// Set safe note icon name
			TextView safeNoteIconNameTextView = (TextView)view.findViewById(R.id.safeNoteIconNameRow);
			if (safeNoteIconNameTextView != null)
			{
				safeNoteIconNameTextView.setText(safeNoteIcon);
			}
			
			// Set safe note name text
			TextView safeNoteNameTextView = (TextView)view.findViewById(R.id.safeNoteNameRow);
			if (safeNoteNameTextView != null)
			{
				safeNoteNameTextView.setText(safeNoteName);
			}
			
			// Set safe note category text
			TextView safeNoteCategoryTextView = (TextView)view.findViewById(R.id.safeNoteCategoryNameRow);
			if (safeNoteCategoryTextView != null)
			{
				safeNoteCategoryTextView.setText(safeNoteCategory);
			}
				
			// Set safe note body text
			TextView safeNoteBodyTextView = (TextView)view.findViewById(R.id.safeNoteBodyRow);
			if (safeNoteBodyTextView != null)
			{
				safeNoteBodyTextView.setText(safeNoteBody);
			}
            return view;
        }
        
        public View getGroupView(int groupPosition, boolean isExpanded, View convertView,
                ViewGroup parent) {
            View view = convertView;
            Map<String, String> category = mGroupData.get(groupPosition);

            if (view == null) {
                LayoutInflater vi = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                view = vi.inflate(R.layout.safenote_category_item_row, null);
            }
            TextView categoryName = (TextView) view.findViewById(R.id.safeNoteCategory);
            categoryName.setText(category.get(Constants.SAFE_NOTE_CATEGORY));
            
            TextView categoryNotesCount = (TextView) view.findViewById(R.id.safeNoteCategoryItemsCount);
            String noteString = (getChildrenCount(groupPosition) == 1)?getString(R.string.string_note):getString(R.string.string_notes);
            categoryNotesCount.setText(getChildrenCount(groupPosition) + " " + noteString);
            return view;
        }

        public int getGroupCount() {
    		return  mGroupData.size();
        }
    }
}